package com.apimanage.common.health;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 健康检查管理器
 * 管理所有健康检查器并在应用启动时执行检查
 *
 * @author API管理平台
 */
@Component
public class HealthCheckManager implements ApplicationRunner {
    
    private static final Logger logger = LoggerFactory.getLogger(HealthCheckManager.class);
    
    @Autowired
    private ApplicationContext applicationContext;
    
    private final Map<String, HealthChecker> healthCheckers = new ConcurrentHashMap<>();
    private final List<HealthCheckResult> checkResults = new ArrayList<>();
    private boolean initialized = false;
    private final Set<String> excludedCheckerNames = new HashSet<>();
    
    /**
     * 初始化健康检查管理器
     */
    @PostConstruct
    public void init() {
        // 获取所有实现了HealthChecker接口的Bean
        Map<String, HealthChecker> beans = applicationContext.getBeansOfType(HealthChecker.class);
        beans.entrySet().forEach(entry -> {
            String beanName = entry.getKey();
            HealthChecker checker = entry.getValue();
            
            // 检查是否需要排除该健康检查器
            if (!excludedCheckerNames.contains(beanName)) {
                healthCheckers.put(checker.getName(), checker);
                logger.info("注册健康检查器: {}", checker.getName());
            } else {
                logger.info("排除健康检查器: {}", checker.getName());
            }
        });
        initialized = true;
        logger.info("健康检查管理器初始化完成，共注册了 {} 个健康检查器，排除了 {} 个检查器", 
                healthCheckers.size(), excludedCheckerNames.size());
    }
    
    /**
     * 设置需要排除的健康检查器名称
     * @param checkerBeanNames 要排除的健康检查器Bean名称，多个用逗号分隔
     */
    public void setExcludedCheckers(String checkerBeanNames) {
        if (checkerBeanNames != null && !checkerBeanNames.isEmpty()) {
            String[] names = checkerBeanNames.split(",");
            Arrays.stream(names)
                  .map(String::trim)
                  .filter(name -> !name.isEmpty())
                  .forEach(excludedCheckerNames::add);
        }
    }
    
    /**
     * 在应用启动后执行健康检查
     */
    @Override
    public void run(ApplicationArguments args) {
        if (!initialized) {
            init();
        }
        
        logger.info("开始执行应用启动自检...");
        
        // 执行所有健康检查
        checkResults.clear();
        boolean allHealthy = true;
        
        for (Map.Entry<String, HealthChecker> entry : healthCheckers.entrySet()) {
            HealthChecker checker = entry.getValue();
            HealthCheckResult result = null;
            
            try {
                long startTime = System.currentTimeMillis();
                result = checker.check();
                result.setResponseTime(System.currentTimeMillis() - startTime);
                checkResults.add(result);
                
                if (result.isHealthy()) {
                    logger.info("[✅] {} 健康检查通过 (耗时: {}ms)", result.getComponentName(), result.getResponseTime());
                } else {
                    logger.error("[❌] {} 健康检查失败: {}", 
                            result.getComponentName(), 
                            String.join(", ", result.getMessages()));
                    allHealthy = false;
                }
            } catch (Exception e) {
                logger.error("[❌] {} 健康检查异常: {}", checker.getName(), e.getMessage(), e);
                allHealthy = false;
                
                // 创建异常结果
                if (result == null) {
                    result = new HealthCheckResult(false, checker.getName());
                }
                result.addMessage("检查过程发生异常: " + e.getMessage());
                checkResults.add(result);
            }
        }
        
        if (allHealthy) {
            logger.info("所有健康检查项目通过，应用启动成功！");
        } else {
            logger.error("存在健康检查项目失败，请检查相关服务配置！");
        }
    }
    
    /**
     * 手动触发健康检查
     * @return 所有检查结果
     */
    public List<HealthCheckResult> performHealthChecks() {
        checkResults.clear();
        
        for (HealthChecker checker : healthCheckers.values()) {
            try {
                HealthCheckResult result = checker.check();
                checkResults.add(result);
            } catch (Exception e) {
                logger.error("执行健康检查时发生异常: {}", e.getMessage(), e);
                HealthCheckResult result = new HealthCheckResult(false, checker.getName());
                result.addMessage("检查过程发生异常: " + e.getMessage());
                checkResults.add(result);
            }
        }
        
        return checkResults;
    }
    
    /**
     * 获取上次检查结果
     * @return 上次检查结果
     */
    public List<HealthCheckResult> getLastCheckResults() {
        return new ArrayList<>(checkResults);
    }
    
    /**
     * 添加健康检查器
     * @param checker 健康检查器
     */
    public void addHealthChecker(HealthChecker checker) {
        healthCheckers.put(checker.getName(), checker);
        logger.info("动态添加健康检查器: {}", checker.getName());
    }
}